﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using zdzh.zdmgr.COL;
using zdzh.zdmgr.SFL;

namespace zdzh.zdmgr.UIL.UserControls
{
    /// <summary>
    /// 对象名称：数据分页用户控件
    /// 对象说明：采用DataReader进行高效数据分页，通过关联Repeater、DataGrid或DataList控件进行数据显示。
    /// 作者姓名：爱英思躺（QQ：2415540409）
    /// 编写日期：2010/06/11 15:18:29
    /// </summary>
    public partial class PageBar : System.Web.UI.UserControl
    {
        protected global::System.Web.UI.WebControls.Label LblRecordCount;
        public global::System.Web.UI.WebControls.Label LblCostTime;
        protected global::System.Web.UI.WebControls.Label LblPageSize;
        protected global::System.Web.UI.WebControls.Label LblCurPage;
        protected global::System.Web.UI.WebControls.Label LblPageCount;
        protected global::System.Web.UI.WebControls.ImageButton BtnPageFirst;
        protected global::System.Web.UI.WebControls.ImageButton BtnPagePrev;
        protected global::System.Web.UI.WebControls.ImageButton BtnPageNext;
        protected global::System.Web.UI.WebControls.ImageButton BtnPageLast;
        protected global::System.Web.UI.WebControls.ImageButton BtnJumpPage;
        protected global::System.Web.UI.WebControls.TextBox TextJumpPage;


        private int pageSize;

        // PageBar分页控件，采用Cookies同时缓存多个不同PageBar实例的当前页数，该变量用于控制缓存的数量。
        // 由于Cookies的大小最多为4048个字节，默认仅在Cookies中缓存最近访问的30个PageBar实例的当前页数。
        private const int MaxCookieCacheCount = 10;

        // Cookies中缓存PageBar实例当前页数的保留天数，该变量为0时表示关闭浏览器后就清空缓存。
        private const int MaxCookieCacheDays = 10;



        /// <summary>
        /// PageBar分页控件所关联的Repeater、DataGrid或DataList数据控件，当PageBar分页控件执行DataBind()数据绑定
        /// 方法时，PageBar分页控件会自动将分页后的数据，绑定给关联的Repeater、DataGrid或DataList控件进行显示。
        /// </summary>
        public Control DataControl
        {
            get;
            set;
        }


        /// <summary>
        /// PageBar分页控件的数据源，数据源为数据实体层中所定义的PageData类型。
        /// 重要提示：务必在为PageBar的DataControl属性赋值之后，再为本属性赋值。
        /// </summary>
        public PageData DataSource
        {
            get;
            set;
        }


        /// <summary>
        /// PageBar分页控件采用Get请求或Cookies获取当前页数，为了保证多个PageBar可以在一个WebForm中同时使用，
        /// 采用“关联数据控件名称+_Page”对Url参数及Cookies的键进行命名，该属性返回控制PageBar当前页的参数名称。
        /// </summary>
        public string PageTag
        {
            get
            {
                if (DataControl == null)
                {
                    throw new CustomException("使用PageBar分页控件时，必须先为PageBar指定DataControl属性所关联的Repeater、DataGrid或DataList数据控件。");
                }
                return DataControl.ID + "_Page";
            }
        }


        /// <summary>
        /// 进行数据绑定，将数据源中的IList类型数据，绑定给关联的数据控件进行显示。
        /// </summary>
        public override void DataBind()
        {
            // 对Http请求Url地址所附带的所有参数信息进行重新整理，如"http://localhost/Product.aspx?Type=01&Factory=1911&Page=28"
            // 确保在用户单击上一页下一页等按钮后，PageBar的页数发生变更时，Url地址除了Page之外的参数信息，也可以完整的保留下来。

            string newUrl = Request.Path + "?";
            for (int n = 0; n < Request.QueryString.Count; n++)
            {
                if (Request.QueryString.Keys[n] != PageTag)
                    newUrl += Request.QueryString.Keys[n] + "=" + Request.QueryString[n] + "&";

            }
            newUrl += PageTag + "=";

            if (DataSource.CurPage > DataSource.PageCount)  //如果所请求的当前页大于数据源的总页数，转向到最后1页。
            {
                Response.Redirect(newUrl + DataSource.PageCount);
            }


            LblRecordCount.Text = DataSource.RecordCount.ToString();  //总记录数
            LblPageSize.Text = DataSource.PageSize.ToString();        //每页显示记录数
            LblCurPage.Text = DataSource.CurPage.ToString();          //所请求的当前页数
            LblPageCount.Text = DataSource.PageCount.ToString();      //页面总数
            TextJumpPage.Text = DataSource.CurPage.ToString();        //跳转页面默认为当前面

            BtnPageFirst.Attributes.Add("onclick", "javascript:location='" + newUrl + "1';return false;");
            BtnPagePrev.Attributes.Add("onclick", "javascript:location='" + newUrl + DataSource.PrevPage + "';return false;");
            BtnPageNext.Attributes.Add("onclick", "javascript:location='" + newUrl + DataSource.NextPage + "';return false;");
            BtnPageLast.Attributes.Add("onclick", "javascript:location='" + newUrl + DataSource.PageCount + "';return false;");
            BtnJumpPage.Attributes.Add("onclick", "javascript:location='" + newUrl + "'+document.getElementById('" + TextJumpPage.ClientID + "').value;return false;");

            if (DataControl != null)
            {
                BindDataControl(); // 绑定分页后的数据给所关联的Repeater、DataGrid或DataList数据控件。
            }

            // 将服务端已校验处理后的当前页数，按照“页面路径+页面名称+关联数据控件名称”命名的Cookies主键进行保存。

            HttpCookie pageBarCookie = Request.Cookies["BudStudio.WebControls.PageBar"];
            if (pageBarCookie == null)
            {
                pageBarCookie = new HttpCookie("BudStudio.WebControls.PageBar");
                pageBarCookie[Request.Path + "_" + PageTag] = CurPage.ToString();
            }
            else
            {
                // 由于Cookies的大小最多为4048个字节，默认仅在Cookies中缓存一数量的PageBar实例的当前页数。
                while (pageBarCookie.Values.Count > MaxCookieCacheCount)
                {
                    pageBarCookie.Values.Remove(pageBarCookie.Values.Keys.Get(0));
                }
                pageBarCookie[Request.Path + "_" + PageTag] = CurPage.ToString();
            }

            if (MaxCookieCacheDays > 0)
                pageBarCookie.Expires = DateTime.Now.AddDays(MaxCookieCacheDays);
            Response.Cookies.Add(pageBarCookie);

        }


        /// <summary>
        /// 返回所请求的当前页数，采用Get请求或Cookies获取当前页数，Get请求中的Url参数优先于Cookies缓存。
        /// </summary>
        public int CurPage
        {
            get
            {
                int page = DataValid.GetIntOrZero(Request.QueryString[PageTag]);
                if (page > 0) return page;

                HttpCookie pageBarCookie = Request.Cookies["BudStudio.WebControls.PageBar"];
                if (pageBarCookie != null && pageBarCookie[Request.Path + "_" + PageTag] != null)
                {
                    string pageStr = pageBarCookie[Request.Path + "_" + PageTag];
                    int curPage = DataValid.GetIntOrZero(pageStr);
                    if (curPage > 0)
                    {
                        return curPage;
                    }
                }

                return 1;
            }
        }


        /// <summary>
        /// 每页显示记录数。
        /// </summary>
        public int PageSize
        {
            get
            {
                if (pageSize <= 0)
                {
                    pageSize = 15;
                }
                return pageSize;
            }
            set
            {
                pageSize = value;
            }
        }


        /// <summary>
        /// 绑定分页后的数据给所关联的Repeater、DataGrid或DataList数据控件。
        /// </summary>
        private void BindDataControl()
        {
            //如果存在关联的Repeater控件
            if (DataControl is Repeater)
            {
                Repeater repeater = (Repeater)DataControl;
                repeater.DataSource = DataSource.PageList;
                repeater.DataBind();
            }

            //如果存在关联的DataGrid控件
            if (DataControl is DataGrid)
            {
                DataGrid dataGrid = (DataGrid)DataControl;
                dataGrid.DataSource = DataSource.PageList;
                dataGrid.DataBind();
            }

            //如果存在关联的DataList控件
            if (DataControl is DataList)
            {
                DataList dataList = (DataList)DataControl;
                dataList.DataSource = DataSource.PageList;
                dataList.DataBind();
            }
        }


    }
}
